﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.IO;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.Windows.Forms;
using System.ComponentModel;
using System.Security.Cryptography.X509Certificates;
using HalconDotNet;


namespace ImageDefine
{
    [Serializable]
    public class ImageTask
    {
        public string Name{get;set;}
        public string Remark { get; set; }
        public bool SimplyInfo
        {
            get;
            set;
        }
        public List<ImageDefine.ImageToolBase> listTools;
        [NonSerialized]
        public Dictionary<string,ImageDefine.ImageToolBase> dicTools;
        [NonSerialized]
        public double dTimeUsed;
        [NonSerialized]
        public bool bResultOK;
        [NonSerialized]
        public double dResultX;
        [NonSerialized]
        public double dResultY;
        [NonSerialized]
        public double dResultA;
        [NonSerialized]
        public double dResultScore;
        [NonSerialized]
        public Dictionary<string, string> InputParameters;
        [NonSerialized]
        public Dictionary<string,string> OutPutResults;
        [NonSerialized]
        public HalconDotNet.HImage currentImage;
        [NonSerialized]
        public SmartDisplayControl.SmartDisplayControl displayControl;
        [NonSerialized]
        public DateTime DateTimeDelFileTime;

        [NonSerialized]
        public string strPath;
        [NonSerialized]
        public List<ImageToolResult> ImageTaskResults;
        public ImageTask()
        {
            Name = "";
            Remark = "";
            
            listTools = new List<ImageDefine.ImageToolBase>();
            dicTools = new Dictionary<string, ImageDefine.ImageToolBase>();
            InputParameters = new Dictionary<string, string>();
            OutPutResults = new Dictionary<string, string>();
            
        }
        public void Add(ImageDefine.ImageToolBase newTool)
        {
            listTools.Add(newTool);
            dicTools = listTools.ToDictionary(p => p.strName);

        }
        public void Insert(int index, ImageDefine.ImageToolBase newTool)
        {
            listTools.Insert(index, newTool);
            dicTools = listTools.ToDictionary(p => p.strName);

        }
        public void Remove(int index)
        {
            listTools.RemoveAt(index);
            dicTools = listTools.ToDictionary(p => p.strName);
            //listTasks.Reverse(index,2);

        }
        public void Modify(int index, string strNewName)
        {
            listTools[index].strName = strNewName;
            listTools[index].ModifyName();
            dicTools = listTools.ToDictionary(p => p.strName);
        }
        public void ShiftUp(int index)
        {
            if (index > 0)
            {
                ImageDefine.ImageToolBase currentTool = listTools[index];
                ImageDefine.ImageToolBase upSideTool = listTools[index-1];
                listTools[index - 1] = currentTool;
                listTools[index] = upSideTool;
                dicTools = listTools.ToDictionary(p => p.strName);
            }
        }
        public void ShiftDn(int index)
        {
            if (index < listTools.Count-1)
            {
                ImageDefine.ImageToolBase currentTool = listTools[index];
                ImageDefine.ImageToolBase DnSideTool = listTools[index + 1];
                listTools[index + 1] = currentTool;
                listTools[index] = DnSideTool;
                dicTools = listTools.ToDictionary(p => p.strName);
            }
           
        }
        
        public bool Run(SmartDisplayControl.SmartDisplayControl display)
        {
            displayControl = display;
            GeneralLib.HiPerfTimer timer = new GeneralLib.HiPerfTimer();
            if (InputParameters == null)
            {
                InputParameters = new Dictionary<string, string>();
            }
            if (OutPutResults == null)
            {
                OutPutResults = new Dictionary<string, string>();
            }
            OutPutResults.Clear();
            timer.Start();
            
            bResultOK = true;
            foreach (ImageDefine.ImageToolBase toolItem in listTools)
            {
                  toolItem.Run(currentImage, display);
            }
            foreach (ImageDefine.ImageToolBase toolItem in listTools)
            {
                if (toolItem.bJudgeItem)
                {
                    if (toolItem.bResultOK == false)
                    {
                        bResultOK = false;
                    }
                    dResultX = toolItem.ResultX;
                    dResultY = toolItem.ResultY;
                    dResultA = toolItem.dResultA;
                    dResultScore = toolItem.dResultScore;
                }
            }
           

            

            if (bResultOK)
            {
                display.DispString("Result : OK", 10, 10, "green");
                if (SimplyInfo == false)
                {
                    display.DispString("X Pos  : " + dResultX.ToString("0.000"), "green");
                    display.DispString("Y Pos  : " + dResultY.ToString("0.000"), "green");
                    display.DispString("Angle  : " + dResultA.ToString("0.000"), "green");
                    display.DispString("Score  : " + dResultScore.ToString("0.0"), "green");
                    display.DispString("Time   : " + timer.Duration.ToString("0.000"), "green");
                }
                ImageTaskResults = new List<ImageToolResult>();
                ImageToolBase imageToolLastItem = listTools[listTools.Count - 1];
                for (int i = 0; i < imageToolLastItem.ImageToolResults.Count; i++)
                {
                    ImageTaskResults.Add(imageToolLastItem.ImageToolResults[i]);
                }

            }
            else
            {
                display.DispString("Result : NG", 10, 10, "red");
                if (SimplyInfo == false)
                {
                    display.DispString("X Pos  : " + dResultX.ToString("0.000"), "red");
                    display.DispString("Y Pos  : " + dResultY.ToString("0.000"), "red");
                    display.DispString("Angle  : " + dResultA.ToString("0.000"), "red");
                    display.DispString("Score  : " + dResultScore.ToString("0.0"), "red");
                    display.DispString("Time   : " + timer.Duration.ToString("0.000"), "red");
                }
            }
            return true;
        }
        public string GetOutPutResult(string strOutputName)
        {
            if (OutPutResults.ContainsKey(strOutputName)==false)
            {
                throw (new Exception("输出结果中没有:" + strOutputName + "成员"));
            }
            return OutPutResults[strOutputName];
        }
        public string GetItemOutPutResult(string strItemName,string strOutputName)
        {
            if (dicTools.ContainsKey(strItemName) == false)
            {
                throw (new Exception("任务中没有:" + strItemName + "子工具"));
            }
            if (dicTools[strItemName].OutPutResults.ContainsKey(strOutputName)==false)
            {
                throw (new Exception("子工具输出结果中没有:" + strOutputName + "成员"));
            }
            return dicTools[strItemName].OutPutResults[strOutputName];
        }
       
        public bool SaveRunningImage(string strImagePath,string strImageName,bool SaveOrgImage,bool SaveProcessImage,bool bJpeg=false)
        {
            if (currentImage == null)
            {
                return false;
            }
            
            if (SaveOrgImage)
            {
                string strPathTemp = strImagePath + @"\";// + @"/HisteryProImageOK/" + strName + @"/";
                if (!Directory.Exists(strPathTemp))
                {
                    Directory.CreateDirectory(strPathTemp);

                }
                string strFileName = strPathTemp + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "_" + strImageName;
                if (bJpeg)
                {
                    currentImage.WriteImage("jpeg 20", 0, strFileName);
                }
                else
                {
                    currentImage.WriteImage("bmp", 0, strFileName);
                }
                
            }
            if (SaveProcessImage)
            {
                string strPathTemp = strImagePath +@"\";// + @"/HisteryProImageOK/" + strName + @"/";
                if (!Directory.Exists(strPathTemp))
                {
                    Directory.CreateDirectory(strPathTemp);
                            
                }
                string strFileName = strPathTemp +DateTime.Now.ToString("yyyyMMddHHmmssfff")+"_"+ strImageName + "";
                displayControl.hWindow.DumpWindowImage().WriteImage("jpg", 0, strFileName);
            }
            
            DeleteOldFiles(strImagePath,3);

            return true;
        }
        void DeleteOldFiles(string dir, int days)
        {
            if ((DateTime.Now - DateTimeDelFileTime).TotalDays < 1)
            {
                return;
            }
            try
            {
                if ((DateTime.Now - DateTimeDelFileTime).Days > 1)
                {
                    DateTimeDelFileTime = DateTime.Now;
                    if (!Directory.Exists(dir) || days < 1)
                        return;
                    if (Directory.GetFileSystemEntries(dir).Length < 1000)
                        return;
                    var now = DateTime.Now;
                    foreach (var f in Directory.GetFileSystemEntries(dir).Where(f => File.Exists(f)))
                    {
                        var t = File.GetCreationTime(f);

                        var elapsedTicks = now.Ticks - t.Ticks;
                        var elapsedSpan = new TimeSpan(elapsedTicks);

                        if (elapsedSpan.TotalDays > days) File.Delete(f);
                    }
                    
                }
                    
            }
            catch (Exception)
            {
                // ignored
            }
        }

        public bool RunFileImage(SmartDisplayControl.SmartDisplayControl display,HalconDotNet.HImage incomeImg)
        {
            displayControl = display;
            currentImage = incomeImg;
            GeneralLib.HiPerfTimer timer = new GeneralLib.HiPerfTimer();
            if (InputParameters == null)
            {
                InputParameters = new Dictionary<string, string>();
            }
            if (OutPutResults == null)
            {
                OutPutResults = new Dictionary<string, string>();
            }
            OutPutResults.Clear();
            timer.Start();

            bResultOK = true;
            foreach (ImageDefine.ImageToolBase toolItem in listTools)
            {
                

                if (toolItem.GetType().ToString().IndexOf("ImageToolGrab") > -1)
                {
                    
                }
                else
                {
                    toolItem.Run(currentImage, display);
                }
            }
            foreach (ImageDefine.ImageToolBase toolItem in listTools)
            {
                if (toolItem.bJudgeItem)
                {
                    if (toolItem.bResultOK == false)
                    {
                        bResultOK = false;
                    }
                    dResultX = toolItem.ResultX;
                    dResultY = toolItem.ResultY;
                    dResultA = toolItem.dResultA;
                    dResultScore = toolItem.dResultScore;
                }
            }

            if (bResultOK)
            {
                display.DispString("Result : OK", 10, 10, "green");
                if (SimplyInfo == false)
                {
                    display.DispString("X Pos  : " + dResultX.ToString("0.000"), "green");
                    display.DispString("Y Pos  : " + dResultY.ToString("0.000"), "green");
                    display.DispString("Angle  : " + dResultA.ToString("0.000"), "green");
                    display.DispString("Score  : " + dResultScore.ToString("0.0"), "green");
                    display.DispString("Time   : " + timer.Duration.ToString("0.000"), "green");
                }
                ImageTaskResults = new List<ImageToolResult>();
                ImageToolBase imageToolLastItem = listTools[listTools.Count - 1];
                for (int i = 0; i < imageToolLastItem.ImageToolResults.Count; i++)
                {
                    ImageTaskResults.Add(imageToolLastItem.ImageToolResults[i]);
                }
            }
            else
            {
                display.DispString("Result : NG", 10, 10, "red");
                if (SimplyInfo == false)
                {
                    display.DispString("X Pos  : " + dResultX.ToString("0.000"), "red");
                    display.DispString("Y Pos  : " + dResultY.ToString("0.000"), "red");
                    display.DispString("Angle  : " + dResultA.ToString("0.000"), "red");
                    display.DispString("Score  : " + dResultScore.ToString("0.0"), "red");
                    display.DispString("Time   : " + timer.Duration.ToString("0.000"), "red");
                }
            }
            return true;
        }

        public bool RunRegeditFileImage(SmartDisplayControl.SmartDisplayControl display)
        {
            HalconDotNet.HImage incomeImg = GetRegeditFile();
            display.ShowImage(incomeImg);
            RunFileImage(display, incomeImg);
            return true;
        }
        public void WriteRegeditFile(SmartDisplayControl.SmartDisplayControl display)
        {
            if (display.ho_Image == null)
                return;

            if (!Directory.Exists(strPath + @"\" + Name + @"\"))
            {
                Directory.CreateDirectory(strPath + @"\" + Name + @"\");

            }
            display.ho_Image.WriteImage("tiff", 0, strPath + @"\" + Name + @"\" + @"\regiterImage" + ".tiff");
            return;
        }
        public void LoadRegeditFile(SmartDisplayControl.SmartDisplayControl display)
        {
            try
            {
                HalconDotNet.HImage hImage = new HalconDotNet.HImage();
                hImage.ReadImage(strPath + @"\" + Name + @"\" + @"\regiterImage" + ".tiff");
                if (hImage != null)
                {
                    display.ShowImage(hImage);
                }

            }
            catch
            {
                
            }
            return;
        }
        public HalconDotNet.HImage GetRegeditFile()
        {
            try
            {
                HalconDotNet.HImage hImage = new HalconDotNet.HImage();
                hImage.ReadImage(strPath + @"\" + Name + @"\" + @"\regiterImage" + ".tiff");
                return hImage;
            }
            catch
            {
                return null;
            }
           
        }
    }
}
